-- 运营活动: 达标竞技


--[[
{
    cmd_id = 1, -- 命令id，用于批量停止、删除活动 
    act_id = 97, -- 活动id (97 万宝轮盘)
    act_name = "万宝轮盘", -- 活动名称
    act_desc = "活动期间每2小时刷新一次商品！", -- 活动描述
    beg_time = 1518364800,  -- 活动开始时间(unix timestamp)
    end_time = 1594044800,  -- 活动结束时间(unix timestamp)
    config = -- 配置数据
    {
        ItemList = 
        {
            { 
                itemIdx = 1, type = 0, id = 508, count = 1, weight = 210, buyNumLimit = 1, broadcast = 0, bind = 1,},
            },
            { 
                itemIdx = 2, type = 0, id = 508, count = 1, weight = 210, buyNumLimit = 1, broadcast = 0, bind = 1,},
            },
            { 
                itemIdx = 3, type = 0, id = 508, count = 1, weight = 210, buyNumLimit = 1, broadcast = 0, bind = 1,},
            },
            { 
                itemIdx = 4, type = 0, id = 508, count = 1, weight = 210, buyNumLimit = 1, broadcast = 0, bind = 1,},
            },
            { 
                itemIdx = 5, type = 0, id = 508, count = 1, weight = 210, buyNumLimit = 1, broadcast = 0, bind = 1,},
            },
            { 
                itemIdx = 6, type = 0, id = 508, count = 1, weight = 210, buyNumLimit = 1, broadcast = 0, bind = 1,},
            },
            { 
                itemIdx = 7, type = 0, id = 508, count = 1, weight = 210, buyNumLimit = 1, broadcast = 0, bind = 1,},
            },
            { 
                itemIdx = 8, type = 0, id = 508, count = 1, weight = 210, buyNumLimit = 1, broadcast = 0, bind = 1,},
            },
            { 
                itemIdx = 9, type = 0, id = 508, count = 1, weight = 210, buyNumLimit = 1, broadcast = 0, bind = 1,},
            },
            { 
                itemIdx = 10, type = 0, id = 508, count = 1, weight = 210, buyNumLimit = 1, broadcast = 0, bind = 1,},
            },
            { 
                itemIdx = 11, type = 0, id = 508, count = 1, weight = 210, buyNumLimit = 1, broadcast = 0, bind = 1,},
            },
        },
        everyCountNeedGold = 100,   --没充值多少元宝获得一次
        firstRefreshCost = 10,                  --手工刷新费用
        refreshCostAdd = 10,                    --手工刷新费用(增加)
        drawNum = 6,                --抽取4个物品
    },
}
]]

-- 检查配置是否正确，正确则返回 0，否则返回错误码
function oper_act_97_check_cfg(cfg)
    if cfg == nil then return 20 end
    
    local config = cfg.config
    if config == nil then return 21 end
    
    if config.ItemList == nil then return 23 end
    if type(config.ItemList) ~= "table" then return 24 end
  
    if not oper_act_check_one_award_cfg(config.ItemList) then
        return 22
    end 

    return 0
end

-- 安装活动，成功则返回 0，否则返回错误码
function oper_act_97_setup(cfg) 
    return 0
end

-- 卸载活动
function oper_act_97_unsetup(cfg)   
end

-- 活动开始
function oper_act_97_start(cfg)
    local ssVar = System.getStaticVar()
    ssVar.oper_act_97_start = 1
    ssVar.oper_act_97_cmd = cfg.cmd_id
    ssVar.oper_act_97_act = cfg.act_id

    local data = gRankMgr_GetValueByIndx(0, RANK_DEFINE_OPERATION_97, 1)

    if data then
        local myData = BaseFuc_unserialize(data)
        if myData and myData.cmd_id and myData.cmd_id == cfg.cmd_id and myData.act_id and myData.act_id == cfg.act_id and
            myData.time and cfg.beg_time <= myData.time and  cfg.end_time > myData.time then
            return
        end
    end

    gRankMgr_Clear(RANK_DEFINE_OPERATION_97)
end

-- 活动结束
function oper_act_97_end(cfg)
    local ssVar = System.getStaticVar()
    ssVar.oper_act_97_start = nil
    ssVar.oper_act_97_cmd = nil
    ssVar.oper_act_97_act = nil

end

-- 打包数据
function oper_act_97_packet_data(sysarg, cfg)
    if not cfg then return end
    local config = cfg.config
    if not config then return end

    local actorid = Actor.getActorId(sysarg)

    local data = gRankMgr_GetValueById(actorid, RANK_DEFINE_OPERATION_97, 1)

    local myData = BaseFuc_unserialize(data)

    if not myData then
        myData = {}
    end

    if not myData.myGold then
        myData.myGold = 0
    end

    if not myData.myUseCount then
        myData.myUseCount = 0
    end

    local time = System.getSystemTime()
    local needRefresh = false

    if not myData.myRefreshData then
        myData.myRefreshData = {}
        needRefresh = true
    elseif myData.mySelfTime and not System.isUnixTimeSameDay(myData.mySelfTime, time) then
        myData.myRefreshData = {}
        needRefresh = true
    end

    if not myData.myRefreshCount then
        myData.myRefreshCount = 0
    elseif myData.mySelfTime and not System.isUnixTimeSameDay(myData.mySelfTime, time) then
        myData.myRefreshCount = 0
    end

    if needRefresh then
        local choiceItemList = GetItemIdxsRand(config.ItemList, config.drawNum) 
        for idx = 1, #choiceItemList do
            myData.myRefreshData[idx] = {}
            myData.myRefreshData[idx].idx = choiceItemList[idx].itemIdx
            myData.myRefreshData[idx].state = 0
        end

        if not myData.cmd_id then
            myData.cmd_id = cfg.cmd_id
            myData.act_id = cfg.act_id
            myData.time = time
        end

        if not myData.sex then
            myData.sex = Actor.getIntProperty(sysarg, PROP_ACTOR_SEX)
            myData.vocation = Actor.getIntProperty(sysarg, PROP_ACTOR_VOCATION)
        end

        myData.mySelfTime = time

        local newData = BaseFuc_serialize(myData)
        gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_97, 1, newData)
    end
    

    local pack = oper_act_alloc_init_data_packet(sysarg, cfg.cmd_id, cfg.act_id)
    if (pack == nil) then
        return
    end
    DataPack.writeInt(pack, myData.myGold)
    DataPack.writeInt(pack, myData.myUseCount)
    DataPack.writeShort(pack, myData.myRefreshCount)
    local len = config.drawNum
    DataPack.writeByte(pack, len)
    for ii = 1, len do
        if not myData.myRefreshData[ii] then
            myData.myRefreshData[ii] = {}
        end
        DataPack.writeShort(pack, myData.myRefreshData[ii].idx or 0)
        DataPack.writeByte(pack, myData.myRefreshData[ii].state or 0)
    end
    DataPack.flush(pack)
end

-- 操作，返回操作结果，0为成功
function oper_act_97_do(sysarg, cfg, clientPkt)
    if cfg == nil then return end
    
    if cfg.state == nil or cfg.state ~= 1 then -- 不在活动中
        Actor.sendTipmsg(sysarg,Lang.ScriptTips.Operation001, ttFlyTip)
        return
    end
    
    local config = cfg.config
    if config == nil then -- 参数错误
        print("error, oper_act_97_do cfg.config confg error")
        return
    end

    local actorid = Actor.getActorId(sysarg)

    local data = gRankMgr_GetValueById(actorid, RANK_DEFINE_OPERATION_97, 1)

    local myData = BaseFuc_unserialize(data)

    if not myData then
        myData = {}
    end

    if not myData.myGold then
        myData.myGold = 0
    end

    if not myData.myUseCount then
        myData.myUseCount = 0
    end

    --[[
    local time = System.getSystemTime()
    if not myData.cmd_id then
        myData.cmd_id = cfg.cmd_id
        myData.act_id = cfg.act_id
        myData.time = time
    end
    myData.mySelfTime = time
    ]]
    local time = System.getSystemTime()
    local opType = DataPack.readByte(clientPkt)
    --print("opType ="..opType)
    if opType == 1 then
        local myCount = math.floor(myData.myGold/config.everyCountNeedGold)
        if myCount <= myData.myUseCount then
            Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation241, ttFlyTip)
            return
        elseif Item.getBagEmptyGridCount( sysarg ) <= 0 then
            Actor.sendTipmsg(sysarg, Lang.ScriptTips.COM0015, ttFlyTip)
            return
        end


        local needRefresh = false

        local dVar = Actor.getDyanmicVar(sysarg)
        if dVar.oper_act_97_reward_index then
            needRefresh = operation_act_97_send_awards(sysarg, cfg, myData)
            dVar.oper_act_97_reward_index = nil
        end
        
        if not myData.myRefreshData then
            needRefresh = true
        elseif myData.mySelfTime and not System.isUnixTimeSameDay(myData.mySelfTime, time) then
            needRefresh = true
        end

        if not myData.myRefreshCount then
            myData.myRefreshCount = 0
        elseif myData.mySelfTime and not System.isUnixTimeSameDay(myData.mySelfTime, time) then
            myData.myRefreshCount = 0
        end
        local needSendAll = false
        if needRefresh then
            myData.myRefreshData = {}
            local choiceItemList = GetItemIdxsRand(config.ItemList, config.drawNum) 
            for idx = 1, #choiceItemList do
                myData.myRefreshData[idx] = {}
                myData.myRefreshData[idx].idx = choiceItemList[idx].itemIdx
                myData.myRefreshData[idx].state = 0
            end
            needSendAll = true
        end

        myData.myUseCount = myData.myUseCount + 1

        if not myData.cmd_id then
            myData.cmd_id = cfg.cmd_id
            myData.act_id = cfg.act_id
            myData.time = time
        end

        if not myData.sex then
            myData.sex = Actor.getIntProperty(sysarg, PROP_ACTOR_SEX)
            myData.vocation = Actor.getIntProperty(sysarg, PROP_ACTOR_VOCATION)
        end

        myData.mySelfTime = time

        local newData = BaseFuc_serialize(myData)
        gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_97, 1, newData)

        if needSendAll then
            oper_act_97_packet_data(sysarg, cfg)
        end

        local list = {}
        for idx = 1, #myData.myRefreshData do
            if myData.myRefreshData[idx] and myData.myRefreshData[idx].state == 0 then
                table.insert(list, config.ItemList[myData.myRefreshData[idx].idx])
            end
        end

        local index, item = GetItemIdxRandExt(list)

        dVar.oper_act_97_reward_index = item.itemIdx

        local netPack = oper_act_alloc_do_result_packet(sysarg, cfg.cmd_id, cfg.act_id, 0)
        if not netPack then return end
        --print("opType ="..opType)
        --print("index ="..index)
        --print("myData.myScore ="..myData.myScore)
        DataPack.writeByte(netPack, opType) 
        DataPack.writeInt(netPack, myData.myUseCount) 
        DataPack.writeShort(netPack, dVar.oper_act_97_reward_index)

    --  DataPack.writeByte(netPack, 1) -- 活动特有参数
        DataPack.flush(netPack)
    elseif opType == 3 then
        local needRefresh = false

        local dVar = Actor.getDyanmicVar(sysarg)
        if dVar.oper_act_97_reward_index then
            needRefresh = operation_act_97_send_awards(sysarg, cfg, myData)
            dVar.oper_act_97_reward_index = nil
        end

        local time = System.getSystemTime()
        
        if not myData.myRefreshData then
            needRefresh = true
        elseif myData.mySelfTime and not System.isUnixTimeSameDay(myData.mySelfTime, time) then
            needRefresh = true
        end

        if not myData.myRefreshCount then
            myData.myRefreshCount = 0
        elseif myData.mySelfTime and not System.isUnixTimeSameDay(myData.mySelfTime, time) then
            myData.myRefreshCount = 0
        end

        if needRefresh then
            myData.myRefreshData = {}
            local choiceItemList = GetItemIdxsRand(config.ItemList, config.drawNum) 
            for idx = 1, #choiceItemList do
                myData.myRefreshData[idx] = {}
                myData.myRefreshData[idx].idx = choiceItemList[idx].itemIdx
                myData.myRefreshData[idx].state = 0
            end

            if not myData.cmd_id then
                myData.cmd_id = cfg.cmd_id
                myData.act_id = cfg.act_id
                myData.time = time
            end

            if not myData.sex then
                myData.sex = Actor.getIntProperty(sysarg, PROP_ACTOR_SEX)
                myData.vocation = Actor.getIntProperty(sysarg, PROP_ACTOR_VOCATION)
            end

            myData.mySelfTime = time

            local newData = BaseFuc_serialize(myData)
            gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_97, 1, newData)

            oper_act_97_packet_data(sysarg, cfg)
        else
            local costNum = myData.myRefreshCount * config.refreshCostAdd + config.firstRefreshCost
            local refreshConsume  = { { type = 10, id = 0, count = costNum,} }        --手工刷新费用
            if not CheckConsumeCond( sysarg, refreshConsume, 1 ) then
                return
            end
            if not DoConsumeCond( sysarg, refreshConsume, 1, LogIds.OperationLogId097, Lang.LogTips.Operation097) then
                return
            end
            myData.myRefreshCount = myData.myRefreshCount + 1
            myData.myRefreshData = {}
            local choiceItemList = GetItemIdxsRand(config.ItemList, config.drawNum) 
            for idx = 1, #choiceItemList do
                myData.myRefreshData[idx] = {}
                myData.myRefreshData[idx].idx = choiceItemList[idx].itemIdx
                myData.myRefreshData[idx].state = 0
            end

            if not myData.cmd_id then
                myData.cmd_id = cfg.cmd_id
                myData.act_id = cfg.act_id
                myData.time = time
            end

            if not myData.sex then
                myData.sex = Actor.getIntProperty(sysarg, PROP_ACTOR_SEX)
                myData.vocation = Actor.getIntProperty(sysarg, PROP_ACTOR_VOCATION)
            end

            myData.mySelfTime = time

            local newData = BaseFuc_serialize(myData)
            gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_97, 1, newData)

            oper_act_97_packet_data(sysarg, cfg)
        end
    elseif opType == 2 then
        local dVar = Actor.getDyanmicVar(sysarg)
        if not dVar.oper_act_97_reward_index then
            Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation005, ttFlyTip)
            return
        end
        local itemIdx = dVar.oper_act_97_reward_index
        local needRefresh = operation_act_97_send_awards(sysarg, cfg, myData, 1)  -- 为1表示需要更新数据并弹窗
        dVar.oper_act_97_reward_index = nil

        if needRefresh then
            myData.myRefreshData = {}
            local choiceItemList = GetItemIdxsRand(config.ItemList, config.drawNum) 
            for idx = 1, #choiceItemList do
                myData.myRefreshData[idx] = {}
                myData.myRefreshData[idx].idx = choiceItemList[idx].itemIdx
                myData.myRefreshData[idx].state = 0
            end

            if not myData.cmd_id then
                myData.cmd_id = cfg.cmd_id
                myData.act_id = cfg.act_id
                myData.time = time
            end

            if not myData.sex then
                myData.sex = Actor.getIntProperty(sysarg, PROP_ACTOR_SEX)
                myData.vocation = Actor.getIntProperty(sysarg, PROP_ACTOR_VOCATION)
            end

            myData.mySelfTime = time

            local newData = BaseFuc_serialize(myData)
            gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_97, 1, newData)
            oper_act_97_packet_data(sysarg, cfg)
        end
    end
end

--下线
function oper_act_97_logout(sysarg)
    local ssVar = System.getStaticVar()
    if not ssVar.oper_act_97_start then
        return
    end
    if not ssVar.oper_act_97_cmd then
        return
    end
    if not ssVar.oper_act_97_act then
        return
    end
    
    local cfg = get_oper_act_cfg(ssVar.oper_act_97_cmd, ssVar.oper_act_97_act)
    if not cfg then
        return
    end

    local config = cfg.config
    if not config then
        return
    end 
    local actorid = Actor.getActorId(sysarg)

    local data = gRankMgr_GetValueById(actorid, RANK_DEFINE_OPERATION_97, 1)

    local myData = BaseFuc_unserialize(data)

    if not myData then
        myData = {}
    end
    operation_act_97_send_awards(sysarg, cfg, myData)
end

function operation_act_97_send_awards(sysarg, cfg, myData, needTip)
    if not cfg then
        return false
    end

    local config = cfg.config
    if not config then
        return false
    end 
    if not myData then
        return
    end
    local myRefreshData = myData.myRefreshData
    if not myRefreshData then
        return false
    end
    local dVar = Actor.getDyanmicVar(sysarg)
    local actorid = Actor.getActorId(sysarg)
    if dVar.oper_act_97_reward_index then
        local curIndex
        local needRefresh = true
        for idx = 1, #myRefreshData do
            if myRefreshData[idx] and myRefreshData[idx].idx == dVar.oper_act_97_reward_index and  myRefreshData[idx].state == 0 then
                curIndex = idx
            elseif myRefreshData[idx] and myRefreshData[idx].idx ~= dVar.oper_act_97_reward_index and  myRefreshData[idx].state == 0 then
                needRefresh = false
            end
        end
        if not curIndex then
            return false
        end
        if dVar.oper_act_97_reward_index <= #config.ItemList then
            local item = config.ItemList[dVar.oper_act_97_reward_index]
            if IsBagGridEnough(sysarg, {item}) then
                Awards.Give(sysarg,{item},LogIds.OperationLogId097,Lang.LogTips.Operation097)
            else
                local title = Lang.ScriptTips.Operation057
                local content = Lang.ScriptTips.Operation058
                local sex = Actor.getIntProperty(sysarg, PROP_ACTOR_SEX)
                local vocation = Actor.getIntProperty(sysarg, PROP_ACTOR_VOCATION)
                Awards.GiveToMailById(actorid, {item}, title, content, LogIds.OperationLogId097, Lang.LogTips.Operation097, vocation, sex)
            end 
            if item.broadcast and item.broadcast > 0 then
                local noticeStr = string.format(Lang.ScriptTips.Operation242, Actor.getName(sysarg), Item.getItemLinkMsg(item.id))
                System.broadcastTipmsg(noticeStr, ttScreenCenter + ttChatWindow)
            end
            if needRefresh then
                if needTip then
                    local netPack = oper_act_alloc_do_result_packet(sysarg, cfg.cmd_id, cfg.act_id, 0)
                    if not netPack then return end
                    DataPack.writeByte(netPack, 2) 
                    DataPack.writeShort(netPack, dVar.oper_act_97_reward_index) 
                    DataPack.writeByte(netPack, 1)
                    DataPack.writeByte(netPack, 2)  --表示获得物品弹窗，但是不更新数据（列表整体更新）
                    DataPack.flush(netPack)
                end
                return true
            else
                local time = System.getSystemTime()
                myRefreshData[curIndex].state = 1
                if not myData.cmd_id then
                    myData.cmd_id = cfg.cmd_id
                    myData.act_id = cfg.act_id
                    myData.time = time
                end

                if not myData.sex then
                    myData.sex = Actor.getIntProperty(sysarg, PROP_ACTOR_SEX)
                    myData.vocation = Actor.getIntProperty(sysarg, PROP_ACTOR_VOCATION)
                end

                myData.mySelfTime = time

                local newData = BaseFuc_serialize(myData)
                gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_97, 1, newData)

                local netPack = oper_act_alloc_do_result_packet(sysarg, cfg.cmd_id, cfg.act_id, 0)
                if not netPack then return end
                DataPack.writeByte(netPack, 2) 
                DataPack.writeShort(netPack, dVar.oper_act_97_reward_index) 
                DataPack.writeByte(netPack, 1)
                DataPack.writeByte(netPack, needTip or 0)  --默认为0只更新数据不弹窗
                DataPack.flush(netPack)
            end
        end
    end
    return false
end

function oper_act_97_withdrawyuanbao(sysarg, value)
    if value <= 0 then
        return
    end

    local ssVar = System.getStaticVar()
    if not ssVar.oper_act_97_start then
        return
    end
    if not ssVar.oper_act_97_cmd then
        return
    end
    if not ssVar.oper_act_97_act then
        return
    end
    
    local cfg = get_oper_act_cfg(ssVar.oper_act_97_cmd, ssVar.oper_act_97_act)
    if not cfg then
        return
    end

    local config = cfg.config
    if not config then
        return
    end 

    local actorid = Actor.getActorId(sysarg)

    local data = gRankMgr_GetValueById(actorid, RANK_DEFINE_OPERATION_97, 1)

    local myData = BaseFuc_unserialize(data)

    if not myData then
        myData = {}
    end

    if not myData.myGold then
        myData.myGold = 0
    end

    myData.myGold = myData.myGold + value
    
    local time = System.getSystemTime()
    if not myData.cmd_id then
        myData.cmd_id = cfg.cmd_id
        myData.act_id = cfg.act_id
        myData.time = time
    end
    myData.mySelfTime = time
    local newData = BaseFuc_serialize(myData)
    gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_97, 1, newData)

    
    oper_act_97_packet_data(sysarg, cfg)
end

--[[
-- 跨天
function oper_act_97_new_day_arrive(act_id) 

end

]]